using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using static XLFrame.UnityObjectConverter;
using XLFrame.NodeEditor.Extensions;

namespace XLFrame
{
    /// <summary>
    /// JsonObject 自定义反序列化,支持Unity对象
    /// </summary>
    public class JsonObjectConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(JsonObject);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JObject jObject = JObject.Load(reader);
            var typeString = jObject["Type"].Value<string>();
            var valueToken = jObject["Value"];

            Type type = Type.GetType(typeString);
            if (type == null)
                throw new JsonSerializationException($"无法找到类型 '{typeString}'。");

            object value = null;

            if (type == typeof(UnityEngine.Object) || type.IsSubclassOf(typeof(UnityEngine.Object)))
            {
                jObject["value"] = jObject;
                value = JsonUtility.FromJson<JsonUnityObject>(jObject.ToString()).value;
            }
            else
            {
                value = valueToken.ToObject(type, serializer);
            }

            return new JsonObject(value);
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            JsonObject jsonObject = (JsonObject)value;
            JObject jObject = new JObject
            {
                ["Type"] = jsonObject.Type,
            };

            if (typeof(UnityEngine.Object).IsAssignableFrom(Type.GetType(jsonObject.Type)))
            {
                jObject["instanceID"] = new JValue(((UnityEngine.Object)jsonObject.Value)?.GetInstanceID());
            }
            else
            {
                jObject["Value"] = JToken.FromObject(jsonObject.Value, serializer);
            }
            jObject.WriteTo(writer);
        }
    }

    /// <summary>
    /// 序列化和反序列化的Json数据,代替object,可正常序列化和反序列化Object对象内容不会丢失
    /// </summary>
    [JsonConverter(typeof(JsonObjectConverter))]
    [System.Serializable]
    public class JsonObject
    {
        /// <summary>
        /// object 的类型 
        /// </summary>
        public string Type;
        public object Value;

        public JsonObject(object value)
        {
            Value = value;
            var type = value.GetType();
            Type = type.GetTypeNameAndAssembly();
        }
    }
}